﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace August.UI
{
    public class Circle : ShapeBase
    {

        public GraphicsPath ScaleGraphicPath = new GraphicsPath();
        public float Radiusx;
        public float Radiusy;
        public Circle(float x, float y, float radiusX, float radiusY)
        {
            PointFs = new PointF[1];
            PointFs[0].X = x;
            PointFs[0].Y = y;
            Radiusx = radiusX;
            Radiusy = radiusY;
        }

        public Circle(float x, float y, float radius)
        {
            PointFs = new PointF[1];
            PointFs[0].X = x;
            PointFs[0].Y = y;
            Radiusx = radius;
            Radiusy = radius;
        }

        internal override void OnWheelPaint(PaintEventArgs e)
        {
            Circle circle = this;
            PointF[] m_pointFs = new PointF[1] { new PointF(circle.PointFs[0].X, circle.PointFs[0].Y) };
            float radiusx = circle.Radiusx;
            float radiusy = circle.Radiusy;
            using (System.Drawing.Drawing2D.Matrix transform = new Matrix())
            {
                transform.Scale(Parent.Owner.ScaleX, Parent.Owner.ScaleY, System.Drawing.Drawing2D.MatrixOrder.Append);
                transform.Translate(Parent.Owner.OffsetX, Parent.Owner.OffsetY, System.Drawing.Drawing2D.MatrixOrder.Append);
                transform.TransformPoints(m_pointFs);
                radiusx = radiusx * Parent.Owner.ScaleX;
                radiusy = radiusy * Parent.Owner.ScaleY;
                circle.TransForm = transform.Clone();
                circle.LastPointFs = m_pointFs;
            }
            RectangleF rectangleF = new RectangleF(m_pointFs[0].X - radiusx, m_pointFs[0].Y - radiusy, radiusx * 2, radiusy * 2);
            GraphicsPath graphicsPath = new GraphicsPath();
            graphicsPath.AddEllipse(rectangleF);
            circle.ScaleGraphicPath = (GraphicsPath)graphicsPath.Clone();
            graphicsPath.AddPath(CreateCrossGraphicPath(m_pointFs[0], 6, 0), false);
            e.Graphics.DrawPath(new Pen(circle.m_DrawColor, circle.DrawLineWidth), graphicsPath);
            circle.DrawRegion = new Region(graphicsPath);
            circle.DrawGraphicsPath = graphicsPath;
            circle.MoveGraphicPath = CreateCrossGraphicPath(m_pointFs[0], 6, 0);
            base.OnWheelPaint(e);
        }

        internal override bool OnDownPaint(MouseEventArgs e)
        {
            m_IsSelectedPoint = false;
            m_IsScale = false;
            if (this.DrawGraphicsPath.IsOutlineVisible(e.X, e.Y, new Pen(Color.Empty, DrawLineWidth + 6)))
            {
                m_isSelected = true;
                m_DrawColor = ShapeBase.ColorMouseDown;
                m_mouseDownMovePointFs = new PointF[PointFs.Length];
                PointFs.CopyTo(m_mouseDownMovePointFs, 0);

                if (MoveGraphicPath.IsOutlineVisible(e.X, e.Y, new Pen(Color.Empty, DrawLineWidth + 6)))
                {
                    m_IsSelectedPoint = true;
                }

                if (ScaleGraphicPath.IsOutlineVisible(e.X, e.Y, new Pen(Color.Empty, DrawLineWidth + 6)))
                {
                    m_IsScale = true;
                }
                return true;
            }
            else
                return false;
        }


        internal override void OnMovePaint(MouseEventArgs e)
        {
            base.OnMovePaint(e);
            if (m_isSelected && IsUserShape)
            {
                if (m_IsSelectedPoint)
                {
                    Point point = e.Location;
                    Matrix matrix = new Matrix();
                    matrix.Translate((-m_mouseDownPointF.X + point.X) * 1f / Parent.Owner.ScaleX, (-m_mouseDownPointF.Y + point.Y) * 1f / Parent.Owner.ScaleY);
                    m_mouseDownMovePointFs.CopyTo(PointFs, 0);
                    PointF[] pointFsOneSelect = new PointF[1] { PointFs[m_selectedPointIndex] };
                    matrix.TransformPoints(pointFsOneSelect);
                    PointFs[m_selectedPointIndex] = pointFsOneSelect[0];
                }
                else if (m_IsScale)
                {
                    Point point = e.Location;
                    double r = Math.Sqrt(Math.Pow((point.X - LastPointFs[0].X) * 1f / Parent.Owner.ScaleX, 2) + Math.Pow((point.Y - LastPointFs[0].Y) * 1f / Parent.Owner.ScaleY, 2));
                    Radiusx = (float)r;
                    Radiusy = (float)r;
                }
            }
        }
        private GraphicsPath CreateCrossGraphicPath(PointF pointF, float radius, float angle)
        {
            float L1x1 = pointF.X - radius;
            float L1y1 = pointF.Y;
            float L1x2 = pointF.X + radius;
            float L1y2 = pointF.Y;
            float L2x1 = pointF.X;
            float L2y1 = pointF.Y - radius;
            float L2x2 = pointF.X;
            float L2y2 = pointF.Y + radius;
            PointF[] pointFs = new PointF[4] { new PointF(L1x1, L1y1), new PointF(L1x2, L1y2), new PointF(L2x1, L2y1), new PointF(L2x2, L2y2) };
            Matrix transform = new Matrix();
            transform.RotateAt(angle, pointF);
            transform.TransformPoints(pointFs);

            GraphicsPath graphicsPath1 = new GraphicsPath();
            graphicsPath1.AddLine(pointFs[0], pointFs[1]);
            GraphicsPath graphicsPath2 = new GraphicsPath();
            graphicsPath2.AddLine(pointFs[2], pointFs[3]);
            graphicsPath1.AddPath(graphicsPath2, false);
            return graphicsPath1;
        }
    }
}
